home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.27-7 / scripts / checkstack.pl < prev    next >
Encoding:
Perl Script  |  2008-10-09  |  4.9 KB  |  170 lines

  1. #!/usr/bin/perl
  2.  
  3. #    Check the stack usage of functions
  4. #
  5. #    Copyright Joern Engel <joern@lazybastard.org>
  6. #    Inspired by Linus Torvalds
  7. #    Original idea maybe from Keith Owens
  8. #    s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
  9. #    Mips port by Juan Quintela <quintela@mandrakesoft.com>
  10. #    IA64 port via Andreas Dilger
  11. #    Arm port by Holger Schurig
  12. #    sh64 port by Paul Mundt
  13. #    Random bits by Matt Mackall <mpm@selenic.com>
  14. #    M68k port by Geert Uytterhoeven and Andreas Schwab
  15. #    AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
  16. #    PARISC port by Kyle McMartin <kyle@parisc-linux.org>
  17. #
  18. #    Usage:
  19. #    objdump -d vmlinux | scripts/checkstack.pl [arch]
  20. #
  21. #    TODO :    Port to all architectures (one regex per arch)
  22.  
  23. # check for arch
  24. #
  25. # $re is used for two matches:
  26. # $& (whole re) matches the complete objdump line with the stack growth
  27. # $1 (first bracket) matches the size of the stack growth
  28. #
  29. # $dre is similar, but for dynamic stack redutions:
  30. # $& (whole re) matches the complete objdump line with the stack growth
  31. # $1 (first bracket) matches the dynamic amount of the stack growth
  32. #
  33. # use anything else and feel the pain ;)
  34. my (@stack, $re, $dre, $x, $xs);
  35. {
  36.     my $arch = shift;
  37.     if ($arch eq "") {
  38.         $arch = `uname -m`;
  39.         chomp($arch);
  40.     }
  41.  
  42.     $x    = "[0-9a-f]";    # hex character
  43.     $xs    = "[0-9a-f ]";    # hex character or space
  44.     if ($arch eq 'arm') {
  45.         #c0008ffc:    e24dd064    sub    sp, sp, #100    ; 0x64
  46.         $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
  47.     } elsif ($arch eq 'avr32') {
  48.         #8000008a:       20 1d           sub sp,4
  49.         #80000ca8:       fa cd 05 b0     sub sp,sp,1456
  50.         $re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
  51.     } elsif ($arch =~ /^i[3456]86$/) {
  52.         #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
  53.         $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%esp$/o;
  54.         $dre = qr/^.*[as][du][db]    (%.*),\%esp$/o;
  55.     } elsif ($arch eq 'x86_64') {
  56.         #    2f60:    48 81 ec e8 05 00 00     sub    $0x5e8,%rsp
  57.         $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%rsp$/o;
  58.         $dre = qr/^.*[as][du][db]    (\%.*),\%rsp$/o;
  59.     } elsif ($arch eq 'ia64') {
  60.         #e0000000044011fc:       01 0f fc 8c     adds r12=-384,r12
  61.         $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
  62.     } elsif ($arch eq 'm68k') {
  63.         #    2b6c:       4e56 fb70       linkw %fp,#-1168
  64.         #  1df770:       defc ffe4       addaw #-28,%sp
  65.         $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
  66.     } elsif ($arch eq 'mips64') {
  67.         #8800402c:       67bdfff0        daddiu  sp,sp,-16
  68.         $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
  69.     } elsif ($arch eq 'mips') {
  70.         #88003254:       27bdffe0        addiu   sp,sp,-32
  71.         $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
  72.     } elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
  73.         $re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
  74.     } elsif ($arch eq 'ppc') {
  75.         #c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
  76.         $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
  77.     } elsif ($arch eq 'ppc64') {
  78.         #XXX
  79.         $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
  80.     } elsif ($arch eq 'powerpc') {
  81.         $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
  82.     } elsif ($arch =~ /^s390x?$/) {
  83.         #   11160:       a7 fb ff 60             aghi   %r15,-160
  84.         $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o;
  85.     } elsif ($arch =~ /^sh64$/) {
  86.         #XXX: we only check for the immediate case presently,
  87.         #     though we will want to check for the movi/sub
  88.         #     pair for larger users. -- PFM.
  89.         #a00048e0:       d4fc40f0        addi.l  r15,-240,r15
  90.         $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
  91.     } elsif ($arch =~ /^blackfin$/) {
  92.         #   0:   00 e8 38 01     LINK 0x4e0;
  93.         $re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o;
  94.     } else {
  95.         print("wrong or unknown architecture \"$arch\"\n");
  96.         exit
  97.     }
  98. }
  99.  
  100. sub bysize($) {
  101.     my ($asize, $bsize);
  102.     ($asize = $a) =~ s/.*:    *(.*)$/$1/;
  103.     ($bsize = $b) =~ s/.*:    *(.*)$/$1/;
  104.     $bsize <=> $asize
  105. }
  106.  
  107. #
  108. # main()
  109. #
  110. my $funcre = qr/^$x* <(.*)>:$/;
  111. my $func;
  112. my $file, $lastslash;
  113.  
  114. while (my $line = <STDIN>) {
  115.     if ($line =~ m/$funcre/) {
  116.         $func = $1;
  117.     }
  118.     elsif ($line =~ m/(.*):\s*file format/) {
  119.         $file = $1;
  120.         $file =~ s/\.ko//;
  121.         $lastslash = rindex($file, "/");
  122.         if ($lastslash != -1) {
  123.             $file = substr($file, $lastslash + 1);
  124.         }
  125.     }
  126.     elsif ($line =~ m/$re/) {
  127.         my $size = $1;
  128.         $size = hex($size) if ($size =~ /^0x/);
  129.  
  130.         if ($size > 0xf0000000) {
  131.             $size = - $size;
  132.             $size += 0x80000000;
  133.             $size += 0x80000000;
  134.         }
  135.         next if ($size > 0x10000000);
  136.  
  137.         next if $line !~ m/^($xs*)/;
  138.         my $addr = $1;
  139.         $addr =~ s/ /0/g;
  140.         $addr = "0x$addr";
  141.  
  142.         my $intro = "$addr $func [$file]:";
  143.         my $padlen = 56 - length($intro);
  144.         while ($padlen > 0) {
  145.             $intro .= '    ';
  146.             $padlen -= 8;
  147.         }
  148.         next if ($size < 100);
  149.         push @stack, "$intro$size\n";
  150.     }
  151.     elsif (defined $dre && $line =~ m/$dre/) {
  152.         my $size = "Dynamic ($1)";
  153.  
  154.         next if $line !~ m/^($xs*)/;
  155.         my $addr = $1;
  156.         $addr =~ s/ /0/g;
  157.         $addr = "0x$addr";
  158.  
  159.         my $intro = "$addr $func [$file]:";
  160.         my $padlen = 56 - length($intro);
  161.         while ($padlen > 0) {
  162.             $intro .= '    ';
  163.             $padlen -= 8;
  164.         }
  165.         push @stack, "$intro$size\n";
  166.     }
  167. }
  168.  
  169. print sort bysize @stack;
  170.